package com.example.springredis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@RestController
public class MyController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("test1")
    public String test1() {
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return null;
        });

        stringRedisTemplate.opsForValue().set("key1","111");
        String s = stringRedisTemplate.opsForValue().get("key1");
        System.out.println("s: " + s);

        //incr自增1
        stringRedisTemplate.opsForValue().increment("key1");
        s = stringRedisTemplate.opsForValue().get("key1");
        System.out.println("s: " + s);

        //decr自减1
        stringRedisTemplate.opsForValue().decrement("key1");
        s = stringRedisTemplate.opsForValue().get("key1",0,-1);
        System.out.println("s: " + s);

        //自增n，n可以为整数也可以为浮点数
        stringRedisTemplate.opsForValue().increment("key1",-10);
        stringRedisTemplate.opsForValue().increment("key1",13.14);
        s = stringRedisTemplate.opsForValue().get("key1",0,-1);
        System.out.println("s: " + s);

        //根据范围设置和获取字符类项
        stringRedisTemplate.opsForValue().set("key1","nihao",1);
        s = stringRedisTemplate.opsForValue().get("key1",0,-1);
        System.out.println("s: " + s);

        return "OK";
    }

    @RequestMapping("/test2")
    public String test2() {
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return null;
        });

        //一次头插入一个数据
        stringRedisTemplate.opsForList().leftPush("key1","111");
        List<String> list = stringRedisTemplate.opsForList().range("key1",0,-1);
        System.out.println("list: " + list); //[111]

        //一次头插入多个数据
        stringRedisTemplate.opsForList().leftPushAll("key1","222","333","444");
        list = stringRedisTemplate.opsForList().range("key1",0,-1);
        System.out.println("list: " + list); //[444,333,222,111]

        //一次尾插多个数据
        stringRedisTemplate.opsForList().rightPushAll("key2","111","222","333");
        list = stringRedisTemplate.opsForList().range("key2",0,-1);
        System.out.println("list: " + list); //[111,222,333]

        //头删
        String s = stringRedisTemplate.opsForList().leftPop("key1");
        System.out.println("s: " + s); //444

        //尾删
        s = stringRedisTemplate.opsForList().rightPop("key2");
        System.out.println("s: " + s); //333

        //除了区间之外的所有数据都删除
        stringRedisTemplate.opsForList().trim("key1",0,0);
        list = stringRedisTemplate.opsForList().range("key1",0,-1);
        System.out.println("list: " + list); //[333]

        return "OK";
    }

    @RequestMapping("/test3")
    public String test3() {
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return null;
        });

        //添加一个元素和根据范围获取元素
        stringRedisTemplate.opsForHash().put("key1","f1","111");
        String s = (String)stringRedisTemplate.opsForHash().get("key1","f1");
        System.out.println(s); //111

        //一次添加多个元素并且一次获取多个指定元素
        Map<Object,Object> map = new HashMap<>();
        map.put("f1","111");
        map.put("f2","222");
        map.put("f3","333");
        stringRedisTemplate.opsForHash().putAll("key2",map);
        Set<Object> set = new HashSet<>();
        set.add("f1");
        set.add("f2");
        set.add("f3");
        List<Object> list = stringRedisTemplate.opsForHash().multiGet("key2",set);
        System.out.println(list); //[111,222,333]

        //判断元素是否村子啊
        boolean b = stringRedisTemplate.opsForHash().hasKey("key2","f1");
        System.out.println(b); //true
        b = stringRedisTemplate.opsForHash().hasKey("key2","k7");
        System.out.println(b); //false

        //获取所有的field
        set = stringRedisTemplate.opsForHash().keys("key2");
        System.out.println(set); //[f1,f2,f3]

        //获取所有的value
        list = stringRedisTemplate.opsForHash().values("key2");
        System.out.println(list); //[111,222,333]

        //获取所有的键和值
        map = stringRedisTemplate.opsForHash().entries("key2");
        System.out.println(map); //{f1=111,f2=222,f3=333}

        //自增
        stringRedisTemplate.opsForHash().increment("key2","f2",20);
        s = (String)stringRedisTemplate.opsForHash().get("key2","f2");
        System.out.println(s); //242

        //获取hash中元素个数
        Long len = stringRedisTemplate.opsForHash().size("key2");
        System.out.println(len); //3

        //删除元素
        stringRedisTemplate.opsForHash().delete("key2","f2");
        len = stringRedisTemplate.opsForHash().size("key2");
        System.out.println(len); //2

        return "OK";
    }

    @RequestMapping("/test4")
    public String test4() {
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return null;
        });

        //添加元素并且获取所有所有的元素
        stringRedisTemplate.opsForSet().add("key1","111","222","333");
        Set<String> set = stringRedisTemplate.opsForSet().members("key1");
        System.out.println(set); //[111,222,333]

        //判断元素是否存在
        Boolean b = stringRedisTemplate.opsForSet().isMember("key1","222");
        System.out.println(b); //true
        b = stringRedisTemplate.opsForSet().isMember("key1","666");
        System.out.println(b); //false

        //获取set中元素个数
        Long len = stringRedisTemplate.opsForSet().size("key1");
        System.out.println(len); //3

        //随机删除一个元素
        String s = stringRedisTemplate.opsForSet().pop("key1");
        System.out.println(s); //333

        //求给定集合的交集并且将交集结果放在目标集合中
        stringRedisTemplate.opsForSet().add("key2","111","222","666","000");
        set = stringRedisTemplate.opsForSet().intersect("key1","key2");
        System.out.println(set); //[111,222]
        stringRedisTemplate.opsForSet().intersectAndStore("key1","key2","key3");
        set = stringRedisTemplate.opsForSet().members("key3");
        System.out.println(set); //[111,222]

        return "OK";
    }

    @RequestMapping("/test5")
    public String test5() {
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return null;
        });

        //向zset中一次添加一个元素和分数，并且根据范围获取元素
        stringRedisTemplate.opsForZSet().add("key1","zhangsan",93.5);
        Set<String> set = stringRedisTemplate.opsForZSet().range("key1",0,-1);
        System.out.println(set); //[zhangsan]

        //一次添加多个元素并且获取元素的值和分数
        Set<ZSetOperations.TypedTuple<String>> tuples = new HashSet<>();
        ZSetOperations.TypedTuple<String> tuple1 = new DefaultTypedTuple<>("zhangsan",93.5);
        ZSetOperations.TypedTuple<String> tuple2 = new DefaultTypedTuple<>("lisi",95.0);
        ZSetOperations.TypedTuple<String> tuple3 = new DefaultTypedTuple<>("wangwu",99.5);
        tuples.add(tuple1);
        tuples.add(tuple2);
        tuples.add(tuple3);
        stringRedisTemplate.opsForZSet().add("key2",tuples);
        Set<ZSetOperations.TypedTuple<String>> result = stringRedisTemplate.opsForZSet().rangeWithScores("key2",0,-1);
        System.out.println(result); //[DefaultTypedTuple [score=93.5, value=zhangsan], DefaultTypedTuple [score=95.0, value=lisi], DefaultTypedTuple [score=99.5, value=wangwu]]

        //获取zset的元素个数
        Long len = stringRedisTemplate.opsForZSet().size("key2");
        System.out.println(len); //3

        //获取对应元素的排序
        Long rank = stringRedisTemplate.opsForZSet().rank("key2","wangwu");
        System.out.println(rank); //2
        rank = stringRedisTemplate.opsForZSet().reverseRank("key2","wangwu");
        System.out.println(rank); //0

        //获取给定元素的交集并将交集放进目标元素中
        stringRedisTemplate.opsForZSet().intersectAndStore("key1","key2","key3");
        result = stringRedisTemplate.opsForZSet().rangeWithScores("key3",0,-1);
        System.out.println(result); //[DefaultTypedTuple [score=187.0, value=zhangsan]]

        //删除zset中的最大值和最小值
        ZSetOperations.TypedTuple<String> t = stringRedisTemplate.opsForZSet().popMax("key2");
        System.out.println(t); //DefaultTypedTuple [score=99.5, value=wangwu]
        t = stringRedisTemplate.opsForZSet().popMin("key2");
        System.out.println(t); //DefaultTypedTuple [score=93.5, value=zhangsan]

        return "OK";
    }
}
